
% *******************************************
% SECTION
% *******************************************
\section{Lab Environment Setup} 

Please download the \texttt{Labsetup.zip} file to your VM from the lab’s website, 
unzip it, and you will get a folder called \texttt{Labsetup}. All the files 
needed for this lab are included in this folder.


% -------------------------------------------
% SUBSECTION
% -------------------------------------------
\subsection{Turning off Countermeasures} 

Before starting this lab, we need to make sure the 
address randomization countermeasure is turned off; otherwise, the 
attack will be difficult. 
You can do it using the following command:

\begin{lstlisting}
$ sudo /sbin/sysctl -w kernel.randomize_va_space=0
\end{lstlisting}
 

% -------------------------------------------
% SUBSECTION
% -------------------------------------------
\subsection{The Vulnerable Program} 
\label{sec:vulnerable_program}

The vulnerable program used in this lab is called
\texttt{stack.c}, which is in the \texttt{server-code} folder.
This program has a buffer-overflow vulnerability,
and your job is to exploit this vulnerability and gain the root privilege.
The code listed below has some non-essential information removed,
so it is slightly different from what you get from the lab setup file.

\begin{lstlisting}[language=C, caption={The vulnerable program \texttt{stack.c}}]
#include <stdlib.h>
#include <stdio.h>
#include <string.h>

/* Changing this size will change the layout of the stack.
 * Instructors can change this value each year, so students
 * won't be able to use the solutions from the past. */
#ifndef BUF_SIZE
#define BUF_SIZE 100
#endif

int bof(char *str)
{
    char buffer[BUF_SIZE];

    /* The following statement has a buffer overflow problem */ 
(*@\ifdefined\arm
\ \ \ \ memcpy(buffer, str, 517);       
\else
\ \ \ \ strcpy(buffer, str);          
\fi@*)

    return 1;
}

void foo(char *str)
{
    ...
    bof(str);
}

int main(int argc, char **argv)
{
    char str[517];

    int length = fread(str, sizeof(char), 517, stdin);
    foo(str);
    fprintf(stdout, "==== Returned Properly ====\n");
    return 1;
}
\end{lstlisting}

The above program has a buffer overflow vulnerability. It 
reads data from the standard input, and the data are 
eventually copied to another buffer in the function {\tt bof()}. 
The original input can have a maximum length of \texttt{517} bytes, but the buffer
in {\tt bof()} is only \texttt{BUF\_SIZE} bytes long, which is less than
\texttt{517}. 
\ifdefined\arm
When \texttt{memcpy()} copies the data to the target buffer,
\else
Because {\tt strcpy()} does not check boundaries, 
\fi
buffer overflow will occur.

The program will run on a server with the root privilege, and its 
standard input will be redirected to a TCP connection between the
server and a remote user. 
Therefore, the program actually gets its data from a remote user. 
If users can exploit this buffer overflow vulnerability, 
they can get a root shell on the server. 


\paragraph{Compilation.}
To compile the above vulnerable program, we need to 
turn off the StackGuard and the non-executable stack protections 
using the \texttt{-fno-stack-protector} and \texttt{"-z execstack"} options.
The following is an example of the compilation command (the \texttt{L1} environment 
variable sets the value for the \texttt{BUF\_SIZE} constant inside \texttt{stack.c}).   

\begin{lstlisting}
$ gcc -DBUF_SIZE=$(L1) -o stack -z execstack -fno-stack-protector stack.c
\end{lstlisting}

\ifdefined\arm
\else
We will compile the \texttt{stack} program into both 32-bit and 64-bit 
binaries. Our pre-built Ubuntu 20.04 VM is a 64-bit VM, but it 
still supports 32-bit binaries. All we need to do is to 
use the \texttt{-m32} option in the \texttt{gcc} command. 
For 32-bit compilation, we also use \texttt{-static} to generate 
a statically-linked binary, which is self-contained and not depending
on any dynamic library, because the 32-bit dynamic libraries 
are not installed in our containers. 
\fi

The compilation commands are already provided in \texttt{Makefile}. To compile
the code, you need to type \texttt{make} to execute those commands.
The variables \texttt{L1}, \texttt{L2}, \texttt{L3}, and \texttt{L4} are
set in \texttt{Makefile}; they will be used during the compilation.
After the compilation, we need to copy the binary into
the \texttt{bof-containers} folder, so they can be used by the 
containers. The following commands conduct compilation and 
installation.

\begin{lstlisting}
$ make
$ make install
\end{lstlisting}
 

\paragraph{For instructors (customization).}
To make the lab slightly different from the one offered in the past,
instructors can change the value for \texttt{BUF\_SIZE} by requiring
students to compile the server code using different \texttt{BUF\_SIZE} values.
In \texttt{Makefile}, the \texttt{BUF\_SIZE} value is set by
four variables \texttt{L1}, ..., \texttt{L4}.
Instructors should pick the values for these variables based
on the following suggestions:

\begin{itemize}[noitemsep]
\item \texttt{L1}: pick a number between 100 and 400
\item \texttt{L2}: pick a number between 40 and 200
\item \texttt{L3}: pick a number between 100 and 400
\item \texttt{L4}: pick a number between 20 and 80;
we need to keep this number smaller, to make this level more challenging 
than the previous level. 
\end{itemize}



\paragraph{The Server Program.} 
In the \texttt{server-code} folder, you can find a program called \texttt{server.c}. 
This is the main entry point of the server. It listens to port \texttt{9090}. 
When it receives a TCP connection, it 
invokes the \texttt{stack} program, and sets the TCP connection
as the standard input of the \texttt{stack} program. This way,
when \texttt{stack} reads data from \texttt{stdin}, it actually 
reads from the TCP connection, i.e. the data are provided by
the user on the TCP client side. It is not necessary for 
students to read the source code of \texttt{server.c}.  


% -------------------------------------------
% SUBSECTION
% -------------------------------------------
\subsection{Container Setup and Commands}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\input{\commonfolder/container/setup}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%


\paragraph{Note.} It should be noted that before running 
\texttt{"docker-compose build"} to build the docker
images, we need to compile and copy the server 
code to the \texttt{bof-containers} folder. 
This step is described in Section~\ref{sec:vulnerable_program}.


